package com.dream.common;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.Table;

import net.sf.json.JSONObject;

import org.hibernate.type.DateType;
import org.hibernate.type.IntegerType;
import org.hibernate.type.LongType;
import org.hibernate.type.StringType;
import org.hibernate.type.Type;
import org.springframework.beans.BeanUtils;

@SuppressWarnings("all")
public class ClassUtil {

	private static Map<String, Class<?>> clazMap = new HashMap<String, Class<?>>();
	private static Map<String, Map<String, Type>> classField = new HashMap<String, Map<String,Type>>();
	private static Map<String, Type> heibernateTypMap = new HashMap<String, Type>();
	private static String modelPackPath = "com.dream.model";
	static{
		heibernateTypMap.put("java.lang.String", StringType.INSTANCE);
		heibernateTypMap.put("java.lang.int", IntegerType.INSTANCE);
		heibernateTypMap.put("java.lang.Integer", IntegerType.INSTANCE);
		heibernateTypMap.put("java.util.Date", DateType.INSTANCE);
		heibernateTypMap.put("java.lang.Long", LongType.INSTANCE);
		heibernateTypMap.put("java.lang.long", LongType.INSTANCE);
		
		try {
			scanPackClass(modelPackPath);
		} catch (ClassNotFoundException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public  static Class<?> getClass(String classsName){
		synchronized (clazMap) {
			return clazMap.get(classsName);
		}
	}
	public  static void putClass(Class<?> claz){
		synchronized(clazMap){
			if(claz != null){
				clazMap.put(claz.getName(), claz);
				parseClaszFields(claz);
			}
		}
	}
	public  static Map<String, Type> getClassHeibernateType(String className){
		synchronized(classField){
			return classField.get(className);
		}
	}
	private static void parseClaszFields(Class<?> claz){
		Map<String, Type> map = new HashMap<String, Type>();
		Class<?> superClaz = claz.getSuperclass();
		Field[] fs =  claz.getDeclaredFields();
		for(Field f:fs){
			String name = f.getName();
			if(!"serialVersionUID".equals(name)){
				String type = f.getType().getName();
				map.put(name, heibernateTypMap.get(type));
			}
		}
		
		Field[] superFs = superClaz.getDeclaredFields();
		for(Field f:superFs){
			String name = f.getName();
			if("table_id".equals(name) || "createTime".equals(name) || "showTime".equals(name)){
				String type = f.getType().getName();
				map.put(name, heibernateTypMap.get(type));
			}
		}
		
		classField.put(claz.getName(), map);
	}
	public static String getClassNameByTableName(String tableName){
		StringBuffer sb = new StringBuffer();
		if(tableName.contains("_")){
			String[] arr = tableName.split("_");
			for(String s:arr){
				s = s.substring(0,1).toUpperCase() + s.substring(1, s.length());
				sb.append(s).append("_");
			}
			String result = sb.toString();
			if(result.contains("_")){
				result = result.substring(0, result.lastIndexOf("_"));
			}
			return modelPackPath+"."+result;
		}else{
			tableName = tableName.substring(0,1).toUpperCase() + tableName.substring(1, tableName.length());
			sb.append(modelPackPath).append(".").append(tableName);
		}
		return sb.toString();
	}
	public static void scanPackClass(String pakageName) throws IOException, ClassNotFoundException{
		Enumeration<URL> enumURL = getClassLoader().getResources(
				pakageName.replaceAll("\\.", "/"));
		while (enumURL.hasMoreElements()) {
			URL url = enumURL.nextElement();
			String prot = url.getProtocol();
			if (prot.equals("file")) {
				String packagePath = url.getPath().replaceAll("%20", " ");
				addClass(pakageName, packagePath);
			}
		}
	}
	private static void addClass(String packageName, String packagePath) throws ClassNotFoundException {
		File[] files = new File(packagePath).listFiles(new FileFilter() {

			@Override
			public boolean accept(File file) {
				// TODO Auto-generated method stub
				return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
			}
		});
		for (File e : files) {
			String fileName = e.getName();
			if (e.isFile()) {
				String className = packageName + "."
						+ fileName.substring(0, fileName.lastIndexOf("."));
				putClass(Class.forName(className));
			}
		}
	}
	private static ClassLoader getClassLoader(){
		return Thread.currentThread().getContextClassLoader();
	}
	public static void main(String[] args) {
		System.out.println(JSONObject.fromObject(ClassUtil.getClassHeibernateType("com.dream.model.System_User")));
	}
}
